﻿using System.Collections.Generic;
using System.Security.Principal;

namespace Sidvall.Security
{
    public class ClaimManager
    {
        #region Public Members

        public Sidvall.Security.IClaimsPrincipalManager ClaimsPrincipalManager { get; set; }

        #region AddClaim

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void AddClaim(IIdentity identity, Claim item)
        {
            this.ClaimsPrincipalManager.AddClaim(identity, item);
        }

        #endregion
        #region AddClaims

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void AddClaims(IIdentity identity, IEnumerable<Claim> items)
        {
            this.ClaimsPrincipalManager.AddClaims(identity, items);
        }

        #endregion
        #region ClearClaims

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void ClearClaims(IIdentity identity)
        {
            this.ClaimsPrincipalManager.ClearClaims(identity);
        }

        #endregion
        #region FindClaim

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public Claim FindClaim(IIdentity identity, string claimType)
        {
            return this.ClaimsPrincipalManager.FindClaim(identity, claimType);
        }

        #endregion
        #region FindClaims

        public ClaimCollection FindClaims(IIdentity identity)
        {
            return FindClaims(identity, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ClaimCollection FindClaims(IIdentity identity, string claimType)
        {
            return this.ClaimsPrincipalManager.FindClaims(identity, claimType);
        }

        #endregion
        #region FindClaimValue

        public string FindClaimValue(IIdentity identity, string claimType)
        {
            var item = FindClaim(identity, claimType);
            if (item == null)
                return null;
            return item.Value;
        }
        public string FindClaimValue(IIdentity identity, IEnumerable<string> claimTypes)
        {
            if (claimTypes == null)
                return null;
            foreach (var claimType in claimTypes)
            {
                var item = FindClaim(identity, claimType);
                if (item != null)
                    return item.Value;
            }
            return null;
        }

        #endregion
        #region FindName

        public string FindName(IIdentity identity)
        {
            return FindClaimValue(identity, new string[] { ClaimTypes.Name, ClaimTypes.Name2 });
        }

        #endregion
        #region FindClientId

        public string FindClientId(IIdentity identity)
        {
            return FindClaimValue(identity, ClaimTypes.ClientId);
        }

        #endregion
        #region FindSubjectId

        public string FindSubjectId(IIdentity identity)
        {
            return FindClaimValue(identity, ClaimTypes.Subject);
        }

        #endregion
        #region HasClaim

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool HasClaim(IIdentity identity, string claimType, string value)
        {
            return this.ClaimsPrincipalManager.HasClaim(identity, claimType, value);
        }

        #endregion
        #region MergeClaim

        public Claim MergeClaim(IIdentity identity, string claimType, string value)
        {
            var item = FindClaim(identity, claimType);
            if (value != null)
            {
                if (item != null)
                {
                    item.Value = value;
                }
                else
                {
                    item = new Claim()
                    {
                        ClaimType = claimType,
                        Value = value,
                    };
                    AddClaim(identity, item);
                }
                return item;
            }
            else if (item != null)
            {
                item.Value = null;
            }
            return null;
        }

        #endregion
        #region RemoveClaim

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool RemoveClaim(IIdentity identity, Claim item)
        {
            return this.ClaimsPrincipalManager.RemoveClaim(identity, item);
        }

        #endregion
        #region RemoveClaims

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void RemoveClaims(IIdentity identity, IEnumerable<Claim> items)
        {
            this.ClaimsPrincipalManager.RemoveClaims(identity, items);
        }
        public void RemoveClaims(IIdentity identity, IEnumerable<string> claimTypes)
        {
            if (claimTypes == null)
                return;
            foreach (var claimType in claimTypes)
            {
                var items = FindClaims(identity, claimType);
                RemoveClaims(identity, items);
            }
        }

        #endregion

        #region ToString

        public override string ToString()
        {
            return "ClaimManager - Sidvall.Security.IClaimsPrincipalManager";
        }

        #endregion

        #endregion
        #region Constructors

        public ClaimManager(Sidvall.Security.IClaimsPrincipalManager claimsPrincipalManager)
        {
            this.ClaimsPrincipalManager = claimsPrincipalManager;
        }

        #endregion
    }
}
